package com.hzlx.service;

import com.alibaba.fastjson2.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.hzlx.bean.Order;
import com.hzlx.bean.OrderLineItem;
import com.hzlx.dao.OrderDao;
import com.hzlx.dao.OrderLineItemDao;
import com.hzlx.dto.*;
import io.seata.spring.annotation.GlobalTransactional;
import jakarta.annotation.Resource;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.context.Lifecycle;
import org.springframework.core.ParameterizedTypeReference;
import org.springframework.http.*;
import org.springframework.stereotype.Service;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.client.RestTemplate;

import java.util.*;
import java.util.stream.Collectors;


@Slf4j
@Service
@RequiredArgsConstructor
public class OrderService {
    private final OrderDao orderDao;
    private final OrderLineItemDao orderLineItemDao;
    @Resource
    private  RestTemplate restTemplate;
    @Resource private  ApplicationEventPublisher applicationEventPublisher;
    @GlobalTransactional//全局事务
    public String create(OrderRequest orderRequest ){
        //1、判断库存
        List<Map<String, Object>> skus = orderRequest.getOrderLineItemList()
                .stream()
                .map(orderLine->orderLine.getSku())
                .collect(Collectors.toList());
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_JSON);
        HttpEntity entity = new HttpEntity(skus,headers);// 封装请求体和头
        ParameterizedTypeReference<ResultDto<List<InventoryResponse>>> pt = new ParameterizedTypeReference<>() {};
        ResponseEntity<ResultDto<List<InventoryResponse>>> result =
                restTemplate.exchange("http://inventory-service/api/inventory/isInStock",
                        HttpMethod.POST,
                        entity,
                        pt);
        log.info("库存查询完毕!");
        //如果商品都有库存
       if (result.getBody().getCode().equals("ok") && result.getBody().getData().stream().allMatch(resp->resp.getQuantity()>0)){
           //2、创建订单
           String orderNum = "O-"+ UUID.randomUUID();//自动生成订单号
           //构建订单对象
           Order order = Order.builder()
                   .orderNumber(orderNum)
                   .createdTime(new Date())
                   .orderLineItemList(new ArrayList<>())//空集合
                   .ownerId(orderRequest.getOwnerId())
                   .build();
           orderDao.insert(order);//添加订单
           log.info("订单号{} ~ ~ ~ 订单ID ~~ {}添加完毕!",orderNum,order.getId());
            orderRequest.getOrderLineItemList()
                    .stream()
                    .map(dto-> OrderLineItem.builder()
                            .sku(JSONObject.toJSONString(dto.getSku()))
                            .orderId(order.getId())
                            .quantity(dto.getQuantity())
                            .price(dto.getPrice())
                            .build())
                    .forEach(itemLine-> {
                        orderLineItemDao.insert(itemLine);
                        log.info("详单{}添加成功",itemLine.getSku());
                    });
            log.info("订单详单添加完毕!");
           //3、减少库存
           List<InventoryRequest> list= orderRequest.getOrderLineItemList()
                   .stream()
                   .map(dto-> InventoryRequest.builder()
                           .sku(JSONObject.toJSONString(dto.getSku()))
                           .quantity(dto.getQuantity())
                           .build())
                   .collect(Collectors.toList());
           HttpHeaders inventoryHeaders = new HttpHeaders();
           inventoryHeaders.setContentType(MediaType.APPLICATION_JSON);
           HttpEntity inventoryEntity = new HttpEntity(list,inventoryHeaders);
           //远程调用
           restTemplate.put("http://inventory-service/api/inventory",inventoryEntity);
           log.info("减库存成功！！");
           //4、异步通知
           applicationEventPublisher.publishEvent(orderNum);
           log.info("异步通知完毕！！");
           return orderNum;
       }else {
           throw new IllegalArgumentException("库存不足！！！");
       }
    }
    public PageDto<OrderResponse> find(Integer ownerId, Integer page, Integer rows) {
        IPage<?> pageBean = new Page<>(page,rows);
        IPage<Order> pageResult = orderDao.selectPageVo(pageBean,ownerId);

        return PageDto.<OrderResponse>builder()
                .data(pageResult.getRecords().stream()
                        .map(order -> OrderResponse.builder()
                                .id(order.getId().intValue())
                                .orderNumber(order.getOrderNumber())
                                .createTime(order.getCreatedTime())
                                .build()).collect(Collectors.toList()))
                .page((int) pageResult.getPages())
                .build();
    }
}
